//
//  RaknetHelper.h
//  boxer
//
//  Created by Wu Wang on 11-12-14.
//  Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//

#ifndef boxer_RaknetHelper_h
#define boxer_RaknetHelper_h

#include "GameDefine.h"

#ifdef GAME_USERAKNET

#include "RakPeerInterface.h"
#include "BitStream.h"
#include "MessageIdentifiers.h"

#include "IGCHelper.h"

enum GameIndex
{
	ID_GAME_NPC=ID_USER_PACKET_ENUM+1,
	ID_GAME_LOGING=ID_USER_PACKET_ENUM+2,
	ID_GAME_ROOMING=ID_USER_PACKET_ENUM+3,
	ID_GAME_FIGHTING=ID_USER_PACKET_ENUM+4
};
enum RoomIndex{
	ID_ROOM_RANDOM,
	ID_ROOM_CHALLENGES,
	ID_ROOM_ACCEPT,
	ID_ROOM_REFUSE,
	ID_ROOM_SUCCESS,
	ID_ROOM_QUIT
};
enum FightIndex{
	ID_FIGHT_LEFT,
	ID_FIGHT_RIGHT,
	ID_FIGHT_DOWNATTACT,
	ID_FIGHT_UPWARDATTACT,
	ID_FIGHT_PLAYER_THIS,
	ID_FIGHT_PLAYER_ENEMY,
	ID_FIGHT_ENEMYQUIT,
	ID_FIGHT_VICTORY,
	ID_FIGHT_OVER,
    ID_FIGHT_TEST,
};
enum LoginIndex{
	ID_LOGING_LOGING,
	ID_LOGING_LOGING_SUCCESS,
    ID_LOGING_CREATENAME,
    ID_LOGING_QUIT
};

const unsigned char ID_HOST = 121;
const unsigned char ID_CLIENT = 212;


struct BoxerInfo
{
    unsigned  short m_hp;
    char m_localName[ID_MAX_LENGTH];
    char m_oppoName[ID_MAX_LENGTH];
    unsigned short m_x1;
    unsigned short m_y1;
    unsigned short m_x2;
    unsigned short m_y2;
};

enum PacketType
{
	PACKET_CLIENT,
	PACKET_SREVER,
    PACKET_DELAYTEST
};
enum FightAction
{
    ID_ACTION_LEFTFIST,
    ID_ACTION_RIGHTFIST,
    ID_ACTION_MOVE
};

struct GameInfo
{
    long     m_hp[2];
	long     m_sprite[2];
    float    m_xPos[2];
    float    m_yPos[2];
    unsigned short m_action[2];
	unsigned short m_state[2];
};

enum ClientConmand
{
	COMMAND_MOVE_UP,
	COMMAND_MOVE_DOWN,
	COMMAND_MOVE_LEFT,
	COMMAND_MOVE_RIGHT,
	COMMAND_ATTACK_LEFT,
	COMMAND_ATTACK_RIGHT,
	COMMAND_DEFANSE,
    COMMAND_DEFANSECANCLE,
	COMMAND_DODGE,
	COMMAND_DODGETONORMAL
};
struct ClientPacket
{
	ClientConmand m_command;
};

class CNetworkDelegate
{
public:
    virtual void connectServerSuccessed() {}
    virtual void opponentFound(const BoxerInfo &info) {}
    virtual void receiveServerInfo(const GameInfo &info) {}
	virtual void receiveCommand(const ClientPacket &packet) {}
    virtual void connectServerFailed() {}
    virtual void connectLost() {}
};

class CRaknetHelper
{
    
public:
    
	~CRaknetHelper();
    
    static CRaknetHelper *GetInstance();
	RakNet::RakPeerInterface *GetRakPeer()    {return m_pRakPeer;}
	RakNet::RakNetGUID        GetServerGUID() {return m_serverGuid;}
	bool                      IsHost()        {return m_bHost;}

	void DeallocatePacket(RakNet::Packet *pPacket) {m_pRakPeer->DeallocatePacket(pPacket);}
	RakNet::Packet *ReceivePacket()                {return m_pRakPeer->Receive();}

    bool InitState(const char *szID, int length, CNetworkDelegate *delegate);
    bool ConnectServer();
    bool ConnectRandomRoom();
    bool SendClientCommand(const ClientPacket &packet);
	bool SendServerInfo(const GameInfo &info);
	void DelayTest();
    bool BeginReceiveThread();
	bool StopReceiveThread();
    
private:
    CRaknetHelper();
    void ReceiveData();
    static void *ThreadReceiveData(void *arg);
    
private:
    RakNet::RakPeerInterface *m_pRakPeer;
    RakNet::RakNetGUID        m_serverGuid;
    CNetworkDelegate         *m_pDelegate;
    char                      m_userID[ID_MAX_LENGTH];
    bool                      m_bHost;
    bool                      m_bConnected;
    long                      m_delay;
    
    static pthread_t          m_pid;
    
};


class CAutoMutex
{
public:
	CAutoMutex();
	~CAutoMutex();
    
    static void Init();
    static void Destroy();
private:
	static pthread_mutex_t m_hMutex;
};

#endif

#endif
